
#include "HtmlConverter.h"
#include <stdio.h>
#include <stdexcept>

//---------------------
//--- HtmlConverter ---
//---------------------

const char *HtmlConverter::GetImage(Game *game, size_t x, size_t y)
{
	switch (game->GetField()(x, y).GetOwner())
	{
		case Player1:
			return "dot_blue.bmp";

		case Player2:
			return "dot_red.bmp";

		case None:
			return "dot_white.bmp";

		default:
			throw std::runtime_error("Inner error: unknown player type");
	}
}

void HtmlConverter::GenerateScripts(Game *game, Player targetPlayer, std::string &buffer)
{
	char buf[1024];
	//Storing auxiliary information.
	buffer.append("	<script>\n");
	buf[sprintf(buf, "var width = %d;\n", game->GetField().GetWidth())] = '\0';
	buffer.append(buf);
	buf[sprintf(buf, "var height = %d;\n", game->GetField().GetHeight())] = '\0';
	buffer.append(buf);
	buf[sprintf(buf, "var server_address = \"http://\" + window.location.hostname;\n")] = '\0';
	buffer.append(buf);
	buf[sprintf(buf, "var game_id = \"%ld\";\n", (size_t)game)] = '\0';
	buffer.append(buf);
	buf[sprintf(buf, "var player_id = %d;\n\n", (int)targetPlayer)] = '\0';
	buffer.append(buf);
	//Storing scripts.
	if (game->GetInfo().GetStatus() ==GameInfo::Started &&
		game->GetCurrentPlayer() == targetPlayer)
	{
		//Storing handler for onclick event.
		buffer.append("function onAction(x, y)\n"\
					  "{\n"\
					  "window.location.href = server_address + \"?player=\" + player_id"\
					    									"+ \"&x=\" + x + \"&y=\" + y"\
															"+ \"&game=\" + game_id;\n"\
					  "}\n"\
					  "</script>\n");
	}
	else
	{
		//Storing handler for timer events.
		buffer.append("function updater()"\
					  "{ window.location.href = server_address + \"?player=\" + player_id"\
															  "+ \"&game=\" + game_id; }"\
					  "setInterval(\"updater()\", 5000);"\
					  "</script>\n");
	}
}

void HtmlConverter::GenerateField(Game *game, Player targetPlayer, std::string &buffer)
{
	char buf[1024];
	//Storing table header.
	buffer.append("<center><table border = 1>\n");
	for (size_t y = 0; y < game->GetField().GetHeight(); y++)
	{
		//Storing row.
		buf[sprintf(buf, "<tr height = %d>\n", DEFAULT_CELL_HEIGHT)] = '\0';
		buffer.append(buf);
		for (size_t x = 0; x < game->GetField().GetWidth(); x++)
		{
			//Storing cell.
			buf[sprintf(buf, "<td width = %d>\n", DEFAULT_CELL_WIDTH)] = '\0';
			buffer.append(buf);
			if (game->GetField()(x, y).GetOwner() == None &&
				game->GetCurrentPlayer() == targetPlayer)
				buf[sprintf(buf, "<img src = \"%s\" onclick = \"onAction(%d, %d)\"/>\n",
							GetImage(game, x, y), x, y)] = '\0';
			else
				buf[sprintf(buf, "<img src = \"%s\"/>\n", GetImage(game, x, y), x, y)] = '\0';
			buffer.append(buf);
			buffer.append("</td\n>");
		}
		buffer.append("</tr>\n");
	}
	buffer.append("</table></center>\n");
}

void HtmlConverter::GenerateStats(Game *game, std::string &buffer)
{
	//Getting values.
	size_t player1;
	size_t player2;
	size_t untaken;
	game->GetDotsCount(player1, player2, untaken);
	//Storing names.
	char buf[1024];
	buf[sprintf(buf, "<center><font color = \"0000BB\">%s</font> vs "\
					 "<font color = \"BB0000\">%s</font></center><br/>\n",
					 game->GetInfo().GetPlayer1(), game->GetInfo().GetPlayer2())] = '\0';
	buffer.append(buf);
	//Storing scores.
	buf[sprintf(buf, "<font color = \"0000BB\">Blue player:</font> %d dots <br/>\n", player1)] = '\0';
	buffer.append(buf);
	buf[sprintf(buf, "<font color = \"BB0000\">Red player:</font> %d dots <br/>\n", player2)] = '\0';
	buffer.append(buf);
}

void HtmlConverter::GenerateStarted(Game *game, Player targetPlayer, std::string &buffer)
{
	//Storing head and scripts.
	buffer.append("<html>\n<head><title>Dots Online</title></head>\n<body>\n");
	HtmlConverter::GenerateScripts(game, targetPlayer, buffer);
	//Storing label.
	if (targetPlayer == game->GetCurrentPlayer())
		buffer.append("<h1>Make your move ...</h1>\n");
	else
		buffer.append("<h1>Waiting for another player ...</h1>\n");
	//Creating table with two columns (for game field and statistics).
	buffer.append("<center><table border = 1>\n"\
				  "<tr><td width = 700>\n");
	//Storing game table.
	HtmlConverter::GenerateField(game, targetPlayer, buffer);
	buffer.append("</td>\n"\
				  "<td width = 200>\n");
	//Storing statistics.
	HtmlConverter::GenerateStats(game, buffer);
	buffer.append("</td></tr>\n"\
				  "</table></center>\n");
	//Finishing.
	buffer.append("</body>\n</html>\n");
}

void HtmlConverter::GenerateNotStarted(Game *game, std::string &buffer)
{
	//Storing head and scripts.
	buffer.append("<html>\n<head><title>Dots Online</title></head>\n<body>\n");
	HtmlConverter::GenerateScripts(game, Player::Player1, buffer);
	//Creating label.
	buffer.append("<h1>Waiting for another player ...</h1>\n");
	//Finishing.
	buffer.append("</body>\n</html>\n");
}

void HtmlConverter::GenerateGamePage(Game *game, Player targetPlayer, std::string &buffer)
{
	switch (game->GetInfo().GetStatus())
	{
		case GameInfo::Started:
			GenerateStarted(game, targetPlayer, buffer);
			break;
		case GameInfo::NotStarted:
			GenerateNotStarted(game, buffer);
			break;
	}
}

void HtmlConverter::GenerateMuzzle(std::string &buffer)
{
	buffer.append(
		"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"\
		"<html>"\
		"	<head>"\
		"		<title>Dots Online</title>"\
		"	</head>"\
		"	<body>"\
		"		<h1>Welcome to Dots online</h1>"\
		"		<form ID = \"Muzzle\""\
		"		<p>"\
		"			Username:<br />"\
		"			<input name=\"user_name\" type=\"text\" /><br />"\
		"		</p>"\
		"		<p>"\
		"			Field size:<br />"\
		"			<input name=\"size_x\" type=\"text\" /> * <input name=\"size_y\" type=\"text\" />"\
		"			<br/>"\
		"			<input type=\"submit\" value = \"Start game\">"\
		"		</p>"\
		"		</form>"\
		"	</body>"\
		"</html>");
}
